using System;
using System.Collections.Generic;
using System.Text;

namespace ElteIk.RoboSoccer.Core.Physics
{
	/// <summary>
	/// The game will communicate with the physics engine through this interface.
    /// Basically, the game relies on the world model calculated by the physics engine. 
    /// If you want to override these calculations in a step you need to call the SynchronizeWithGame method.
    /// 
    /// The physicalEngine will be loosely coupled to the game. (= linked and loaded in runtime)
	/// </summary>
	public interface IPhysicsEngine
	{
        /// <summary>
        /// Adds a general physical object to the model.
        /// </summary>
        /// <param name="physicalObject"></param>
		void Add(IPhysicalObject physicalObject);

        /// <summary>
        /// Adds a circle to the physical model.
        /// </summary>
        /// <param name="circle"></param>
		void AddCircle(Circle circle);

        /// <summary>
        /// Adds a polygon (e.g. a rectangle) to the physical model.
        /// </summary>
        /// <param name="polygon"></param>
		void AddPolygon(Polygon polygon);

        /// <summary>
        /// Adds a world (i.e. a bunch of physical objects) to the model.
        /// </summary>
        /// <param name="world"></param>
		void AddWorld(World world);

        /// <summary>
        /// Steps the game model with the given delta amount of time.
        /// </summary>
        /// <param name="delta"></param>
        void Step(float delta);

        /// <summary>
        /// Returns the physical objects that have been collided with the given one.
        /// </summary>
        /// <param name="physicalObject">The method will return objects that have collided with this object.</param>
        /// <returns>A list of collided objects</returns>
        IEnumerable<IPhysicalObject> GetLastColliders(IPhysicalObject physicalObject);

        /// <summary>
        /// In order to override the calculations made by the physics engine (reposition the players and the ball f.e.) you must call this function.
        /// It makes the physical engine update its representation with the world in the game.
        /// </summary>
        void SynchronizeWithGame();

        /// <summary>
        /// Checks for collision. (Playing sound)
        /// </summary>
        /// <returns>True if there was a collision in the previous step.</returns>
        bool WasCollision();

        /// <summary>
        /// Removes all objects from the physical engine. 
        /// </summary>
        void Clear();
    }
}
